﻿using System;
using System.Threading.Tasks;
using Windows.Storage;
using Newtonsoft.Json;
using System.IO;
using System.IO.IsolatedStorage;
using ClumsyWordsPortableLibrary.Shared;

namespace ClumsyWordsWP8
{
    public class CustomDataSerializer<T> : IFileStorage<T>
    {
        public string ReadData(String targetFileName)
        {
            string data = "";

            using (IsolatedStorageFile Storage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (Storage.FileExists(targetFileName))
                {
                    using (IsolatedStorageFileStream stream = Storage.OpenFile(targetFileName, FileMode.Open))
                    {
                        using (StreamReader reader = new StreamReader(stream))
                        {
                            data = reader.ReadToEnd();
                        }
                    }
                }
            }

            return data;
        }

        public void Delete(String targetFileName)
        {
            using (IsolatedStorageFile Storage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (Storage.FileExists(targetFileName))
                {
                    Storage.DeleteFile(targetFileName);
                }
            }
        }

        public void SaveDataToIsolatedStorage(T sourceData, String targetFileName)
        {
            using (IsolatedStorageFile Storage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                using (StreamWriter writer = new StreamWriter(Storage.OpenFile(targetFileName, FileMode.Create)))
                {
                    string data = JsonConvert.SerializeObject(sourceData);
                    writer.Write(data);
                    writer.Flush();
                    IsolatedStorageSettings.ApplicationSettings["LastSaveTime"] = DateTime.Now;
                }
            }
        }

        public async Task SaveAsync(T sourceData, String targetFileName)
        {
            StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(
                targetFileName, CreationCollisionOption.ReplaceExisting);

            Stream writeStream = await file.OpenStreamForWriteAsync();

            using (StreamWriter writer = new StreamWriter(writeStream))
            {
                string data = await JsonConvert.SerializeObjectAsync(sourceData);

                await writer.WriteAsync(data);
                await writer.FlushAsync();
            }
        }

        public async Task<T> LoadAsync(String targetFileName)
        {
            StorageFile file = null;
            bool exists = true;
            try
            {
                 file = await ApplicationData.Current.LocalFolder.GetFileAsync(targetFileName);
            }
            catch (FileNotFoundException)
            {
                exists = false;
            }
            if (!exists)
            {
                await ApplicationData.Current.LocalFolder.CreateFileAsync(targetFileName, CreationCollisionOption.FailIfExists);
                return default(T);
            }

            Stream inStream = await file.OpenStreamForReadAsync();

            using (StreamReader reader = new StreamReader(inStream))
            {
                string data = await reader.ReadToEndAsync();
                reader.Close();
                T model = await JsonConvert.DeserializeObjectAsync<T>(data);
                return model;
            }           
        }

        public async Task DeleteFileAsync(String targetFileName)
        {
            StorageFile file = null;
            bool exists = true;
            try
            {
                file = await ApplicationData.Current.LocalFolder.GetFileAsync(targetFileName);
            }
            catch (FileNotFoundException)
            {
                exists = false;
            }
            if (exists)
            {
                await file.DeleteAsync();
            }
        }
    }
}
